#!/usr/bin/env node
/**
 * Phase2 Step 1.5 强制检查点：生成 reference-component-comparison.json
 * 用法：node scripts/phase2/generate-reference-comparison.js ComponentName ReferenceComponent
 *
 * 遵循 CONTRIBUTING.md 规范和 phase-manifest.json L365 要求
 */

const fs = require('fs');
const path = require('path');
const ts = require('typescript');

/**
 * 从 TypeScript 文件提取 Props 接口定义
 */
function extractPropsInterface(filePath) {
  if (!fs.existsSync(filePath)) {
    throw new Error(`文件不存在: ${filePath}`);
  }

  const source = fs.readFileSync(filePath, 'utf8');
  const sourceFile = ts.createSourceFile(
    path.basename(filePath),
    source,
    ts.ScriptTarget.Latest,
    true
  );

  const props = {};

  function visit(node) {
    if (ts.isInterfaceDeclaration(node) && node.name.text.endsWith('Props')) {
      node.members.forEach(member => {
        if (ts.isPropertySignature(member) && member.name) {
          const propName = member.name.text;
          const typeNode = member.type;

          let typeName = 'unknown';
          if (typeNode) {
            if (ts.isTypeReferenceNode(typeNode)) {
              typeName = typeNode.typeName.text;
              // 检查是否为数组类型
              if (typeNode.typeArguments) {
                typeName = `${typeName}[]`;
              }
            } else if (ts.isArrayTypeNode(typeNode)) {
              const elementType = typeNode.elementType;
              if (ts.isTypeReferenceNode(elementType)) {
                typeName = `${elementType.typeName.text}[]`;
              } else {
                typeName = `${elementType.getText(sourceFile)}[]`;
              }
            } else if (ts.isUnionTypeNode(typeNode)) {
              typeName = typeNode.types.map(t => t.getText(sourceFile)).join('|');
            } else {
              typeName = typeNode.getText(sourceFile);
            }
          }

          props[propName] = typeName;
        }
      });
    }

    ts.forEachChild(node, visit);
  }

  visit(sourceFile);
  return props;
}

/**
 * 加载 DATA_TYPE_CORRECTION_GUIDE 规范
 */
function loadDataTypeGuide() {
  const guidePath = path.join(__dirname, '../../Workflow/FigmaMCPWorkflow/Phase3/DATA_TYPE_CORRECTION_GUIDE.md');

  if (!fs.existsSync(guidePath)) {
    console.warn(`⚠️  DATA_TYPE_CORRECTION_GUIDE.md 未找到，使用默认规范`);
    return {
      iconFields: 'IconItem[]',
      imgFields: 'string',
      hasBgFields: "'Y'|'N'",
      showFields: "'Y'|'N'"
    };
  }

  return {
    iconFields: 'IconItem[]',
    imgFields: 'string | {src: string, width: number, height: number}',
    hasBgFields: "'Y'|'N'",
    showFields: "'Y'|'N'"
  };
}

/**
 * 获取字段类别
 */
function getFieldCategory(fieldName) {
  if (fieldName.endsWith('Icon') || fieldName.includes('icon')) {
    return 'Icon';
  }
  if (fieldName.endsWith('Img') || fieldName.endsWith('Image')) {
    return 'Image';
  }
  if (fieldName.startsWith('has') || fieldName.startsWith('show')) {
    return 'Boolean';
  }
  if (fieldName.endsWith('Color')) {
    return 'Color';
  }
  if (fieldName.endsWith('Size') || fieldName.endsWith('Weight') || fieldName.endsWith('Height')) {
    return 'Typography';
  }
  if (fieldName.endsWith('Margin') || fieldName.endsWith('Padding')) {
    return 'Spacing';
  }
  return 'Generic';
}

/**
 * 获取期望类型
 */
function getExpectedType(fieldName, category, guide) {
  switch (category) {
    case 'Icon':
      return guide.iconFields;
    case 'Image':
      return guide.imgFields;
    case 'Boolean':
      return fieldName.startsWith('has') ? guide.hasBgFields : guide.showFields;
    case 'Color':
      return 'string';
    case 'Typography':
      return 'string | number';
    case 'Spacing':
      return 'string | number';
    default:
      return 'string';
  }
}

/**
 * 比较两个类型是否匹配
 */
function typesMatch(referenceType, currentType) {
  const normalize = (type) => type.replace(/\s+/g, '').toLowerCase();
  return normalize(referenceType) === normalize(currentType);
}

/**
 * 获取 DATA_TYPE_CORRECTION_GUIDE 章节引用
 */
function getGuideSection(category) {
  const sectionMap = {
    'Icon': '第4节 Icon字段标准（IconItem[]）',
    'Image': '第5节 Image字段标准',
    'Boolean': '第1节 Boolean字段规范（\'Y\'|\'N\'）',
    'Color': '第2节 Color字段规范',
    'Typography': '第3节 Typography字段规范',
    'Spacing': '第6节 Spacing字段规范',
    'Generic': '第7节 通用字段规范'
  };
  return sectionMap[category] || '基础规范';
}

/**
 * 生成对比报告
 */
function generateComparison(componentName, referenceComponent) {
  const root = process.cwd();

  // 读取参考组件 Props
  const referenceFile = path.join(
    root,
    'src/components/editor/schema/preview/components',
    referenceComponent,
    'index.tsx'
  );

  // 读取当前组件 Props
  const currentFile = path.join(
    root,
    'src/components/editor/schema/preview/components',
    componentName,
    'index.tsx'
  );

  console.log(`\n📋 Phase2 Step 1.5: 参考组件对比验证`);
  console.log(`  参考组件: ${referenceComponent}`);
  console.log(`  当前组件: ${componentName}`);

  const referenceProps = extractPropsInterface(referenceFile);
  const currentProps = extractPropsInterface(currentFile);
  const guide = loadDataTypeGuide();

  console.log(`  参考组件 Props: ${Object.keys(referenceProps).length} 个字段`);
  console.log(`  当前组件 Props: ${Object.keys(currentProps).length} 个字段`);

  // 生成对比表
  const comparisonTable = [];
  const specialFields = ['titleIcon', 'moreIcon', 'bgImg', 'bgColor', 'hasBg', 'showTitleBar', 'showMore'];
  const specialFieldChecks = {
    fields: [],
    requiredStructure: {
      '*Icon': 'IconItem[]',
      '*Img': 'string | {src, width, height}',
      'has*': "'Y'|'N'",
      'show*': "'Y'|'N'",
      'bgColor': 'string',
      'bgImg': 'string | {src, width, height}'
    },
    allPassed: true
  };

  Object.keys(currentProps).forEach(fieldName => {
    const currentType = currentProps[fieldName];
    const referenceType = referenceProps[fieldName];
    const category = getFieldCategory(fieldName);
    const expectedType = getExpectedType(fieldName, category, guide);
    const match = referenceType ? typesMatch(referenceType, currentType) : null;

    const entry = {
      field: fieldName,
      category,
      referenceType: referenceType || 'N/A',
      currentDesign: currentType,
      match: match === null ? 'N/A' : (match ? true : false),
      dataTypeGuideSection: getGuideSection(category),
      action: match === null
        ? '⚠️  参考组件无此字段'
        : (match ? '✅ 类型正确' : `❌ 类型不匹配，应为 ${expectedType}`)
    };

    comparisonTable.push(entry);

    // 特殊字段检查
    if (specialFields.some(sf => fieldName.includes(sf) || fieldName.endsWith(sf.replace(/^(show|has)/, '')))) {
      specialFieldChecks.fields.push(fieldName);
      if (!match && match !== null) {
        specialFieldChecks.allPassed = false;
      }
    }
  });

  // 统计
  const totalFields = comparisonTable.length;
  const matchedFields = comparisonTable.filter(e => e.match === true).length;
  const mismatchedFields = comparisonTable.filter(e => e.match === false).length;
  const matchRate = totalFields > 0 ? matchedFields / totalFields : 0;

  // 识别阻断项
  const blockers = comparisonTable
    .filter(e => e.match === false && specialFields.some(sf => e.field.includes(sf)))
    .map(e => ({
      field: e.field,
      issue: `类型不匹配: ${e.currentDesign} → 应为 ${e.referenceType}`,
      action: 'Phase2 Step 1.5阻断，必须修正后才能进入Step 2'
    }));

  // 生成报告
  const report = {
    timestamp: new Date().toISOString(),
    currentComponent: componentName,
    referenceComponent,
    referenceFile: `src/components/editor/schema/preview/components/${referenceComponent}/index.tsx`,
    comparisonTable,
    specialFieldChecks,
    summary: {
      totalFields,
      matchedFields,
      mismatchedFields,
      matchRate,
      allSpecialChecksPassed: specialFieldChecks.allPassed
    },
    blockers
  };

  // 保存到 phase2 目录
  const outputDir = path.join(root, componentName, 'phase2');
  if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true });
  }

  const outputFile = path.join(outputDir, 'reference-component-comparison.json');
  fs.writeFileSync(outputFile, JSON.stringify(report, null, 2));

  console.log(`\n✅ 对比报告已生成: ${outputFile}`);
  console.log(`\n📊 统计结果:`);
  console.log(`  总字段数: ${totalFields}`);
  console.log(`  匹配字段: ${matchedFields}`);
  console.log(`  不匹配字段: ${mismatchedFields}`);
  console.log(`  匹配率: ${(matchRate * 100).toFixed(1)}%`);
  console.log(`  特殊字段检查: ${specialFieldChecks.allPassed ? '✅ 通过' : '❌ 未通过'}`);

  if (blockers.length > 0) {
    console.log(`\n❌ 阻断项 (${blockers.length}):`);
    blockers.forEach(b => {
      console.log(`  - ${b.field}: ${b.issue}`);
    });
    console.log(`\n⚠️  Phase2 Step 1.5阻断: 必须修正上述问题才能进入Step 2`);
    process.exit(1);
  }

  if (matchRate < 1.0) {
    console.log(`\n⚠️  匹配率 ${(matchRate * 100).toFixed(1)}% < 100%，建议检查不匹配字段`);
  }

  return report;
}

// CLI 执行
function main() {
  const componentName = process.argv[2];
  const referenceComponent = process.argv[3] || 'JourneyPlanListProd';

  if (!componentName) {
    console.error('❌ 缺少组件名称');
    console.error('用法: node scripts/phase2/generate-reference-comparison.js ComponentName [ReferenceComponent]');
    process.exit(1);
  }

  try {
    generateComparison(componentName, referenceComponent);
  } catch (error) {
    console.error(`\n❌ 生成对比报告失败: ${error.message}`);
    process.exit(1);
  }
}

main();
